<template>
  <div class="operation-monitor-wrap">
    <div class="operation-monitor" id="operation-monitor" v-loading="loading" element-loading-text="拼命加载中">
      <div class="title">
        运行监控
      </div>
      <div class="statistics-wrap">
        <div class="statistics">
          <span class="statistics-label">服务总数：{{statistics.servicetotal}}</span>
          <span class="statistics-label">监测服务：{{statistics.monitor}}</span>
          <span class="statistics-label">正常服务： {{statistics.normal}}</span>
          <span class="statistics-label">异常服务：<span :class="{'font-yellow': statistics.abnormal.length>0}" v-if="statistics.abnormal">{{statistics.abnormal.length}}</span></span>
          <span class="abnormal-tag" v-for="(service,index) in statistics.abnormal" :key="index">
            <at-tag type="red">{{service}}</at-tag>
          </span>
          <span class="statistics-label">监测设备总数：{{statistics.devicetotal}}</span>
          <div class="selection">
              <at-select ref="selection" v-model="selection" placeholder="请选择要监测的服务" collapse-tags @change="changeEvent">
                <at-option
                  v-for="item in list"
                  :key="item.service_id"
                  :label="item.service_name"
                  :value="item.service_id"
                  :disabled="item.disabled"
                >
                </at-option>
              </at-select>
          </div>
        </div>
      </div>
      <div class="service-group">
        <div class="service-wrap" v-for="(service,index) in services" :key="index">
          <div class="service">
            <div class="service-name">
              <span>{{service.name}}</span>
              <span class="delete-btn" @click="deleteEvent(service.id)"><i class="saas-icon-del"></i></span>
            </div>
            <div class="service-monitor">
              <div class="service-status">
                <div class="status">
                  服务运行状态监控
                  <span v-if="service.log.length >0 && service.log[0].status !== null" :class="[service.log[0].status === 3 ? bgRed : (service.log[0].status === 2 ? bgYellow : bgGreen), 'status-label']">
                    {{service.log[0].status === 3 ? '异常' : (service.log[0].status=== 2 ? '停用': '正常') }}
                  </span>
                </div>
                <div class="status-timeline">
                  <!-- <div class="time-total">
                    持续运行状态监控：{{service.servicetime}}小时
                  </div> -->

                  <h5>最近5次监测结果：</h5>
                  <div class="timeline-body">
                    <ul class="timeline-wrap" v-if="service.log.length>0 && service.log[0].status !== null" v-for="(item,index2) in service.log" :key="index2">
                      <li class="timeline-part">
                        <div class="timeline-line">
                          <div class="point">
                          </div>
                          <div :class="{'line': true, 'hidden-line': index2 === service.log.length-1}">
                          </div>
                        </div>
                        <div class="timeline-content">运行状态：<span :class="[item.status === 3 ? fontRed : (item.status === 2 ? fontYellow: fontGreen), 'timeline__status']">{{item.status === 3 ? '异常' : (item.status === 2 ? '停用': '正常') }}</span><br>
                          {{item.log_time}}
                        </div>

                      </li>
                    </ul>
                  </div>
                </div>
              </div>
              <div class="service-environment">
                <div class="status">
                  服务运行环境监控<span v-if="service.devices.length>0" :class="[service.deviceStatus === '异常' ? bgRed : bgGreen, 'status-label']">
                    {{service.deviceStatus}}
                  </span>
                  <span class="datetime">
                    <at-select v-model="interval[service.id]" placeholder="过去12小时" @change="onDateRangeChange($event, service.id)" :id="service.id">
                      <at-option v-for="(item) in translateInterval" :key="item.key" :value="item.value"></at-option>
                    </at-select>
                  </span>
                </div>
                <div class="device-body">
                  <div class="has-device" v-if="service.devices.length>0">
                    <div :class="{'noBorder': index3 === service.devices.length-1, 'part': true}" v-for="(device,index3) in service.devices" :key="index3">
                      <div class="device-statistics">
                        <div class="device">
                          {{device.host_name}} ({{device.ip_addr}})
                        </div>
                        <div class="other">
                          <div class="item">
                            运行状态：<div :class="[device.status >0 ? fontRed : fontGreen, 'label']">{{device.status>0 ? '异常': '正常'}}</div>
                          </div>
                        </div>
                      </div>
                      <div class="condition">
                        <div class="block">
                          <div class="block--top">
                            <div class="block-title">磁盘使用率</div>
                            <div class="block-data">{{device.disk_used}}GB / {{device.disk_space}}GB ({{keepDecimal(device.disk_used*100/device.disk_space, 1)}}%)</div>
                          </div>
                          <div class="chart">
                            <at-progress :percentage="device.disk_pre[device.disk_pre.length-1]" :color=" device.disk_pre[device.disk_pre.length-1] >=90 ? alertRed : normalBlue"></at-progress>
                          </div>
                        </div>
                        <div class="block">
                          <div class="block--top">
                            <div class="block-title">cpu使用率</div>
                            <div class="block-data" v-if="device.cpu_pre.length>0">({{device.cpu_pre[device.cpu_pre.length-1]}}%)</div>
                          </div>
                          
                          <div class="chart" id="echart">
                            <statusLine ref="echart" style="width:100%;height:100%;minWidth:302px" :xData="device.log_time" :seriesData="device.cpu_pre_a"></statusLine>
                          </div>
                        </div>
                        <div class="block">
                          <div class="block--top">
                            <div class="block-title">内存使用情况</div>
                            <div class="block-data">{{device.memory_used}}MB / {{device.memory_space}}MB ({{device.memory_pre[device.memory_pre.length-1]}}%)</div>
                          </div>
                          <div class="chart" id="echart">
                            <statusLine ref="echart" style="width:100%;height:100%;minWidth:302px" :xData="device.log_time" :seriesData="device.memory_pre_a" formatter='<p style="color:#fff;margin-top:11px;margin-left:15px;">{b0}</p><p style="margin-left:10px;margin-right:10px;margin-top:-5px"><svg width="20px" height="20px" version="1.1"><circle cx="10" cy="15" r="4" stroke="#A03FBC" stroke-width="2" fill="#A03FBC"/></svg>{a0}&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{c0}%&nbsp;</p>'></statusLine>
                          </div>
                        </div>
                        <div class="block">
                          <div class="block--top">
                            <div class="block-title">磁盘IO</div>
                            <div class="block-data" v-if="device.write.length>0&&device.read.length>0">{{device.write[device.write.length-1]}}KB/s / {{device.read[device.read.length-1]}}KB/s</div>
                          </div>
                          <div class="chart" id="echart">
                            <statusLine ref="echart" style="width:100%;height:100%;minWidth:302px" :xData="device.log_time" :seriesData="device.disk_IO_a" formatter='<p style="color:#fff;margin-top:11px;margin-left:15px;">{b0}</p><p style="margin-left:10px;margin-right:10px;margin-top:-5px"><svg width="20px" height="20px" version="1.1"><circle cx="10" cy="15" r="4" stroke="#A74FC0"stroke-width="2" fill="#A74FC0"/></svg>{a0}&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{c0}KB/s&nbsp;</p><p style="margin-left:10px;margin-top:-10px;margin-bottom:13px;margin-right:10px;"><svg width="20px" height="20px" version="1.1"><circle cx="10" cy="15" r="4" stroke="#B46926"stroke-width="2" fill="#B46926"/></svg>{a1}&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{c1}KB/s&nbsp;</p>'></statusLine>
                          </div>
                        </div>
                      </div>
                    </div>
                  </div>
                  <div class="no-deivce" v-else>
                    暂无数据
                  </div>
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>
<script>
import { mapGetters, mapActions, mapMutations, mapState } from 'vuex'
import statusLine from '../../components/safeEvents/statasLine'
export default {
  name: 'operationMonitor',
  data () {
    return {
      fontRed: 'font-red',
      fontGreen: 'font-green',
      fontYellow: 'font-yellow',
      bgRed: 'bg-red',
      bgGreen: 'bg-green',
      bgYellow: 'bg-yellow',
      noBorder: 'no-bottom-border',
      selection: '',
      normalBlue: '#8e71c7',
      alertRed: '#f00',
      interval: {},
      translateInterval: [
        { key: '1', value: '过去15分钟', sql: '15 min' },
        { key: '2', value: '过去1小时', sql: '60 min' },
        { key: '3', value: '过去12小时', sql: '12 hour' },
        { key: '4', value: '过去24小时', sql: '24 hour' },
        { key: '5', value: '过去一周', sql: '7 day' },
        { key: '6', value: '过去30天', sql: '30 day' }
      ],
      lastSelection: [],
      // 下拉框不可见
      visible: false
    }
  },
  components: {
    statusLine
  },
  methods: {
    ...mapActions('operationMonitor', [
      'GET_INFORMATION',
      'DELETE_SERVICE',
      'GET_SERVICES',
      'CHOOSE',
      'GET_STATUS'
    ]),
    ...mapMutations('operationMonitor', [
      'SET_DATE_RANGE'
    ]),
    // 保留小数, num 为数字, val是小数点后几位
    keepDecimal (num, val) {
      return num.toFixed(val)
    },
    // 删除监测的服务
    deleteEvent (id) {
      this.Timer()
      let obj = {}
      obj = this.list.find((item) => {
        return item.service_id === id
      })
      this.DELETE_SERVICE({ service_id: id, service_name: obj.service_name })
      this.interval = {}
    },
    // 重新定时
    Timer () {
      if (this.timer) {
        clearInterval(this.timer)
      }
      this.timer = setInterval(() => {
        this.interval = {}
        this.GET_INFORMATION()
        this.GET_SERVICES()
      }, 60000 * 5)
    },
    // 点击选择器可选项
    changeEvent (val) {
      if (this.selection !== '') {
        this.Timer()
        let obj = {}
        obj = this.list.find((item) => {
          return item.service_id === val
        })
        this.CHOOSE({ id: this.selection, service_name: obj.service_name })
        this.selection = ''
        this.interval = {}
      }
    },
    onDateRangeChange (time, id) {
      if (time !== undefined) {
        var interval = ''
        for (let item of this.translateInterval) {
          if (item.value === time) {
            interval = item.sql
            break
          }
        }
        this.GET_STATUS({ interval: interval, service_id: id })
      }
    }
  },
  computed: {
    ...mapState({ changeSizeValue: state => state.system.changeSizeValue }),
    ...mapGetters('operationMonitor', ['services', 'loading', 'statistics', 'list'])
  },
  mounted () {
    this.GET_INFORMATION()
    this.GET_SERVICES()
    this.Timer()
  },
  beforeDestroy () {
    this.interval = {}
  },
  destroyed () {
    clearInterval(this.timer)
  },
  watch: {
    $route (to) {
      if (document.getElementById('echart')) {
        for (let i of this.$refs.echart) {
          if (i.myChart !== null) {
            i.myChart.resize()
          }
        }
      }
      if (to.path !== '/operation/monitor') {
        clearInterval(this.timer)
      } else {
        this.Timer()
      }
    },
    // 监听侧边栏收缩或展开状态echarts自适应
    changeSizeValue () {
      if (document.getElementById('echart')) {
        for (let i of this.$refs.echart) {
          if (i.myChart !== null) {
            i.myChart.resize()
          }
        }
      }
    }
  }
}
</script>
<style scoped>
.service-group {
  padding: 0 20px 20px;
  background: #fff;
  margin-top: -20px;
} 
.title {
  height: 50px;
  line-height: 50px;
  font-weight: bold;
  color: #5c6781;
  font-size: 14px;
  border-bottom: 1px solid #eee;
  padding-left: 20px;
  background: #fff;
}
.operation-monitor {
  background: #ecf0f5;
  font-size: 12px;
  color: #5c6781;
}
.statistics-wrap{
  background: #fff;
  padding: 20px;
}
.operation-monitor .statistics {
  background: #fff;
  border-radius: 2px;
  border: 1px solid #eee;
  height: 50px;
  padding-right: 20px;
  line-height: 50px;
}
.selection {
  float: right;
}
.at-select__tags {
  display: none;
}
.statistics-label {
  padding: 0 20px;
}
.abnormal-tag {
  margin-right: 15px;
}
.service-wrap {
  margin-top: 20px;
}
.service-wrap .service {
  border: 1px solid #eee;
  background: #fff;
  border-radius: 2px;
}
.service-name {
  border-bottom: 1px solid #f0f0f0;
  height: 50px;
  padding-left: 20px;
  font-weight: bold;
  line-height: 50px;
}
.service-monitor {
  padding: 20px 20px;
  overflow: hidden;
}
.service-monitor .service-status {
  border: 1px solid #eee;
  width: 320px;
  float: left;
}
.service-environment {
  border: 1px solid #eee;
  margin-left: 340px;
}
.status {
  padding-left: 20px;
  padding-right: 20px;
  line-height: 40px;
  height: 40px;
  border-bottom: 1px solid #eee;
}
.status-label {
  display: inline-block;
  color: #fff;
  width: 50px;
  height: 25px;
  margin-top: 7px;
  line-height: 25px;
  text-align: center;
}
.service-status .status-label {
  float: right;
  border-radius: 2px;
}
.status-timeline {
  padding: 10px 20px 45px;
  min-height: 140px;
}
.status-timeline h5 {
  font-size: 12px;
  font-weight: normal;
  color: #5c6781;
  padding: 15px 0;
}
.timeline-wrap {
  padding: 0;
  margin: 0;
}
.timeline-part {
  list-style: none;
  display: flex;
  margin-bottom: 5px;
  overflow: hidden;
}
.timeline-content {
  padding-left: 15px;
}
.timeline-line .point {
  border: 1px solid #1F92EF;
  width: 5px;
  height: 5px;
  background: #1F92EF;
  border-radius: 10px;
}
.timeline-line  .line {
  width: 1px;
  height: 40px;
  background: #1F92EF;
  position: relative;
  left: 2px;
  top: 5px;
}
.timeline__status {
  list-style: none;
  margin: 0;
  color: #758697;
  padding-left: 0px;
  position: inherit;
  padding-bottom: 0;
  background: #fff;
}
.hidden-line {
  background: #fff !important;
}
.service-environment .status-label {
  margin-left: 15px;
  border-radius: 2px;
}
.service-environment .device-body {
  position: relative;
  min-height: 120px;
}
.service-group .device-statistics {
  overflow: hidden;
}
.service-group .device-statistics .device {
  float: left;
}
.service-group .device-statistics .other {
  float: right;
}
.other .item {
  float: right;
  padding-left: 30px;
}
.part {
  border-bottom: 1px solid #eee;
  padding-left: 20px;
  padding-bottom: 20px;
}
.noBorder {
  border-bottom: none;
}
.part .device-statistics {
  padding-left: 0px;
  padding-right: 20px;
  margin-top: 20px;
  height: 40px;
  
}
.condition {
  width: 100%;
  display: inline-flex;
}
.condition .chart {
  height: 30px;
}
.condition .block {
  flex: 1;
}
.condition .block--top {
  overflow: hidden;
}
.condition .block-title{
  height: 30px;
  float: left;
}
.condition .block-data {
  float: right;
  padding-right: 20px;
}
.delete-btn {
  float: right;
  margin-right: 17px;
  line-height: 44px;
  font-size: 20px;
  cursor: pointer;
  color: #56adf2;
}
.datetime {
  float: right;
}
.font-yellow {
  color: #ff6600;
}
.font-red {
  color: red;
}
.font-green {
  color: #52CB7B;
}
.bg-red {
  background: red;
}
.bg-green {
  background: #52CB7B;
}
.bg-yellow {
  background: #ff9900;
}
.no-deivce {
  text-align: center;
  height: 140px;
  line-height: 140px;
}
</style>
<style>
.operation-monitor .at-select {
  width: 150px;
  color: #5C6781;
}
.operation-monitor .at-input__icon+.at-input__inner {
  max-height: 36px;
}
.operation-monitor .at-select__tags {
  display: none;
}
.operation-monitor .at-input__icon+.at-input__inner{
  padding-right: 20px;
}
.operation-monitor .selection .at-select-dropdown__item.selected, .operation-monitor .selection .at-select-dropdown__item.selected.hover {
  color: #BFCBD9 !important;
  background-color: #fff !important;
}
.operation-monitor .selection .at-select-dropdown__item.selected {
  color: #BFCBD9;
}
.operation-monitor .at-progress {
  padding-right: 20px;
  position: ratative;
  line-height: 1;
}
.operation-monitor .at-progress-bar {
  padding-right: 0px;
}
.operation-monitor .at-progress__text {
  display: none;
  width: 0;
  padding:0;
  margin: 0;
}
.operation-monitor .at-progress-bar__outer {
  width: 100%;
}
</style>